//
//  myvector.hpp
//  myvector
//
//  Created by s1nzz xie on 2024/9/4.
//

#ifndef myvector_h
#define myvector_h

#include <stdlib.h>
#include <iostream>
#include <assert.h>

#include "RerverseIterator.h"
using namespace std;
namespace  xyx 
{
    template<class T>
    class vector
    {
    public:
        typedef T* iterator;
        typedef const T* const_iterator;
        typedef RerverseIterator<iterator, T&, T*> reverse_iterator;
        typedef RerverseIterator<iterator, const T&, const T*> const_reverse_iterator;

        reverse_iterator rbegin()
        {
            return reverse_iterator(end());
        }

        reverse_iterator rend()
        {
            return reverse_iterator(begin());
        }
        

        iterator begin()
        {
            return start;
        }
        
        const_iterator end()const
        {
            return finish;
        }
        
        const_iterator begin()const
        {
            return start;
        }
        
        iterator end()
        {
            return finish;
        }
        
        vector()
        :start(nullptr)
        ,finish(nullptr)
        ,end_of_storage(nullptr)
        {}
        
        
        
        //[fitst, last)
        template<class InputIterator>
        vector(InputIterator first, InputIterator last)
        {
            while(first != last)
            {
                push_back(*first);
                ++first;
            }
        }
    
        vector(int n, const T& val = T())
        :start(nullptr)
        ,finish(nullptr)
        ,end_of_storage(nullptr)
        {
            resize(n,val);
        }
        
        vector(size_t n, const T& val = T())
        :start(nullptr)
        ,finish(nullptr)
        ,end_of_storage(nullptr)
        {
            resize(n,val);
        }
        
        //传统写法
        vector(const vector<T>& v)
        :start(nullptr)
        ,finish(nullptr)
        ,end_of_storage(nullptr)
        {
            //开辟新空间
            start = new T[v.capacity()];
            //拷贝数据
            //memcpy(start, v.begin(), sizeof(T) * v.size());
            //memcpy会导致深拷贝类出现问题
            for(int i = 0; i < v.size(); ++i)
            {
                start[i] = v.start[i];
            }
            //初始化成员变量
            finish = start + v.size();
            end_of_storage = start + v.capacity();
        }
        
//        //现代写法
//        vector(const vector<T>& v)
//        :start(nullptr)
//        ,finish(nullptr)
//        ,end_of_storage(nullptr)
//        {
//            reserve(v.capacity());
//            for(auto e : v)
//            {
//                push_back(e);
//            }
//        }
        
        void swap(vector<T>& v)
        {
            std::swap(start, v.start);
            std::swap(finish, v.finish);
            std::swap(end_of_storage, v.end_of_storage);
        }
        
        vector&operator=(vector<T> v)
        {
            swap(v);
            
            return *this;
        }
        
        ~vector()
        {
            if(start)
            {
                delete[] start;
                start = finish = end_of_storage = nullptr;
            }
        }
        
        size_t size() const
        {
            return finish - start;
        }
        
        size_t capacity() const
        {
            return end_of_storage - start;
        }
        
        void reserve(size_t n)
        {
            //大于原容量才修改
            if(n > capacity())
            {
                size_t sz = size();
                //开空间
                T* tmp = new T[n];

                if(start)
                {
                    //将原空间数据移到新空间
                    //memcpy存在深拷贝类型
                    //memcpy(tmp,start, sizeof(T) * sz);
                    for(int i = 0; i < sz; ++i)
                    {
                        tmp[i] = start[i];
                    }
                    //释放旧空间
                    delete[] start;
                }
                
                //修改成员变量
                start = tmp;
                finish = start + sz;
                end_of_storage = start + n;
            }
        }

        void pop_back()
        {
            erase(--end());
        }
        
        void push_back(const T& data)
        {
//            //检查容量是否足够
//            if(finish == end_of_storage)
//            {
//                //初始容量为4， 满了就2倍扩容
//                size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
//                reserve(newcapacity);
//            }
//            
//            //尾插
//            *finish = data;
//            ++finish;
            
            insert(end(), data);
        }
        
        T& operator[](size_t pos)
        {
            assert(pos < size());
            
            return start[pos];
        }
        const T& operator[](size_t pos) const
        {
            assert(pos < size());
            
            return start[pos];
        }
        
        iterator insert(iterator pos, const T& data)
        {
            //断言判断pos合法性
            assert(pos <= finish && pos >= start);
            
            //检查容量
            if(finish == end_of_storage)
            {
                //保留偏移量
                size_t len = pos - start;
                
                //扩容逻辑
                size_t newcapacity = capacity() == 0 ? 4 : capacity() * 2;
                reserve(newcapacity);
                
                //恢复pos位置，避免迭代器失效
                pos = start + len;
                
            }
            
            //先挪动数据，再插入数据
            iterator end = finish - 1;
            while(end >= pos)
            {
                *(end) = *(end - 1);
                --end;
            }
            
            *pos = data;
            ++finish;
            
            return pos;
        }
        
        iterator erase(iterator pos)
        {
            assert(pos >= start && pos < finish);
            
            iterator it = pos + 1;
            while(it != finish)
            {
                *(it - 1) = *it;
                it++;
            }
            
            --finish;
            
            return pos;
        }
        
        void resize(size_t n, const T& val = T())
        {
            if(n < size())
            {
                finish = start + n;
            }
            else
            {
                reserve(n); // 可能需要扩容
                
                while (finish != start + n)
                {
                    *finish = val;
                    ++finish;
                }
            }
        }
        
    private:
        iterator start;
        iterator finish;
        iterator end_of_storage;
    };


    void test_1()
    {
        vector<int> v;
        v.push_back(1);
        v.push_back(2);
        v.push_back(3);
        v.push_back(4);
        v.push_back(5);
        v.push_back(5);
        v.push_back(5);
        v.push_back(5);
        v.insert(v.begin(), 100);
        
        for(int e : v)
            std::cout << e << " ";
        std::cout << std::endl;
        
        for(int i = 0; i < v.size(); i++)
        {
            v[i]++;
        }
        
        for(int e : v)
            std::cout << e << " ";
        std::cout << std::endl;
        
        
        v.erase(v.begin());
        v.erase(v.end() - 1);
        for(int e : v)
            std::cout << e << " ";
        std::cout << std::endl;
    }

    void test_2()
    {
        vector<int> v;
        v.push_back(1);
        v.push_back(2);
        v.push_back(3);
        v.push_back(4);
        v.push_back(5);
        
        vector<int>v1(v);
        for(int e : v1)
            std::cout << e << " ";
        std::cout << std::endl;
        
        vector<int>v2 = v1;
        for(int e : v2)
            std::cout << e << " ";
        std::cout << std::endl;
        
        vector<int>v3(3,9);
        for(int e : v3)
            std::cout << e << " ";
        std::cout << std::endl;
    }

    void test_3()
    {
        vector<int> v(10, 1);
        vector<string> v1(10, "1111");

        vector<int> v2(10, 1);



        // vector<int> v;

        for (auto e : v)
        {
            cout << e << " ";
        }
        cout << endl;


        vector<int> v3(v.begin(), v.end());
        for (auto e : v3)
        {
            cout << e << " ";
        }
        cout << endl;

        string str("hello world");
        vector<char> v4(str.begin(), str.end());
        for (auto e : v4)
        {
            cout << e << " ";
        }
        cout << endl;

        int a[] = { 16,2,77,29 };
        vector<int> v5(a, a + 4);
        for (auto e : v5)
        {
            cout << e << " ";
        }
        cout << endl;

    }

    void test_4()
    {
        vector<int> v;
        v.push_back(1);
        v.push_back(2);
        v.push_back(3);
        v.push_back(4);

        for(int e : v)
            std::cout << e << " ";
        std::cout << std::endl;

        vector<int>::reverse_iterator rit = v.rbegin();
        while(rit != v.rend())
        {
            std::cout << *rit << " ";
            ++rit;
        }
        std::cout << std::endl;

    }
}

#endif /* myvector_h */


